package classfile

type CodeAttribute struct {
	cp                     ConstantPool
	attribute_name_index   uint16
	attribute_length       uint32
	max_stack              uint16
	max_locals             uint16
	code_length            uint32
	code                   []byte
	exception_table_length uint16
	exception_table        []*ExceptionTableEntry
	attribute_count        uint16
	attribute_info         []AttributeInfo
}

func (self *CodeAttribute) Code() []byte {
	return self.code
}

func (self *CodeAttribute) MaxLocals() uint16 {
	return self.max_locals
}

type ExceptionTableEntry struct {
	startPc   uint16
	endPc     uint16
	handlerPc uint16
	catchType uint16
}

func (self *CodeAttribute) readInfo(reader *ClassReader) {
	//self.attribute_name_index = reader.readUint16()
	//self.attribute_length = reader.readUint32()
	self.max_stack = reader.readUint16()
	self.max_locals = reader.readUint16()
	self.code_length = reader.readUint32()
	self.code = reader.readBytes(self.code_length)
	self.exception_table_length = reader.readUint16()
	self.exception_table = readExceptionTable(self.exception_table_length, reader)
	self.attribute_count = reader.readUint16()
	self.attribute_info = readAttributes(self.attribute_count, reader, self.cp)
}

func (self *CodeAttribute) MaxStack() uint16 {
	return self.max_stack
}

func readExceptionTable(length uint16, reader *ClassReader) []*ExceptionTableEntry {
	exceptionTable := make([]*ExceptionTableEntry, length)
	for i := range exceptionTable {
		exceptionTable[i] = &ExceptionTableEntry{
			startPc:   reader.readUint16(),
			endPc:     reader.readUint16(),
			handlerPc: reader.readUint16(),
			catchType: reader.readUint16(),
		}
	}
	return exceptionTable
}
